#include <rtthread.h>
#include <drv_gpio.h>
#include "rtdbg.h"
#include <rtdevice.h>
#include "applications/fan/pid.h"

#define TEMP_PWM     "pwm1"
#define TEMP_PWM_CHN     1
#define TEMP_ADC    "adc1"
#define TEMP_ADC_CHN    2

struct rt_device_pwm *temp_dev;
static rt_uint32_t period = 1000000; // 1M = 1,000,000 ns → 1kHz
static rt_uint32_t pulse = 0;

rt_adc_device_t temp_adc_dev;

PID temp_pid = {
    .kp = 400,
    .ki = 100,
    .kd = 400,
    .max_change_i = 40000,
    .max_output = 600000,
    .target = 480
};

static int temp_init(void)
{
    //风枪加热pwm输出初始化
    temp_dev = (struct rt_device_pwm*)rt_device_find(TEMP_PWM);
    if(temp_dev == RT_NULL)
    {
        LOG_E("fan temperature pwm device find errro");
        return RT_ERROR;
    }

    if(rt_pwm_set(temp_dev, TEMP_PWM_CHN, period, pulse) != RT_EOK)
    {
        LOG_E("fan temperature pwm device set message error");
        return RT_ERROR;
    }
    rt_pwm_enable(temp_dev, TEMP_PWM_CHN);

    //风测温ADC输入初始化
    temp_adc_dev = (rt_adc_device_t)rt_device_find(TEMP_ADC);
    if(temp_adc_dev == RT_NULL)
    {
        LOG_E("fan temperature adc device find errro");
        return RT_ERROR;
    }
    rt_adc_enable(temp_adc_dev, TEMP_ADC_CHN);
    
    return RT_EOK;
}
INIT_COMPONENT_EXPORT(temp_init);

/**
 * 温度设置0~5000
 */
void temp_set_period(rt_int32_t pulse_temp)
{
    rt_uint16_t pulse_set = 0;
    if(pulse_temp < 0) pulse_temp = 0;
    if(pulse_temp > period) pulse_temp = period;
    
    rt_pwm_set_pulse(temp_dev, TEMP_PWM_CHN, pulse_temp);
}

rt_uint16_t temp_adc_get_value(void)
{
    // rt_uint32_t value_total = 0;
    // rt_uint16_t value_average;
    // for(rt_uint8_t i=0; i<10; i++)
    // {
    //     value_total += rt_adc_read(temp_adc_dev, TEMP_ADC_CHN);
    //     rt_thread_mdelay(10);
    // } 
    // value_average = (rt_uint16_t) (value_total/10 * 0.20f);

    return rt_adc_read(temp_adc_dev, TEMP_ADC_CHN);;
}

rt_uint16_t temp_set_pid_period(rt_int16_t current_temp, rt_int16_t temp_set_target)
{
    rt_uint32_t temp;
    if (temp_set_target == 0) {
        pid_change_zero(&temp_pid);
    }
    temp = pid_calc(&temp_pid, temp_set_target, current_temp);
    temp_set_period(temp);
    // LOG_D("temp_set_period(temp):%d", temp);
    return 0;
}